using System;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;

namespace EventBehaviorTree
{
    [Serializable]
    public class Repeater : Container
    {
        private int _repeatCount;
        private int _repeatLimit;
        /// <summary>
        /// Repeat 0 times means repeat forever.
        /// </summary>
        private int RepeatLimit { get => _repeatLimit; set => _repeatLimit = Math.Max(0, value); }
        public int RepeatCount { get => _repeatCount; set => _repeatCount = Math.Min(value, RepeatLimit); }

        /// <summary>
        /// Repeat 0 times means repeat forever.
        /// </summary>
        /// <param name="repeatLimit"></param>
        /// <param name="messagePairs"></param>
        /// <param name="silencedMessage"></param>
        public Repeater(int repeatLimit, KeyValuePair<NodeMsg, NodeMsg>[] messagePairs, params NodeMsg[] silencedMessage) :
            base(messagePairs, silencedMessage)
        { RepeatLimit = repeatLimit; }
        public Repeater(int repeatLimit) : base() { RepeatLimit = repeatLimit; }

        public override void NodeEvent(NodeMsg nodeMessage)
        {
            switch (nodeMessage)
            {
                case NodeMsg.Start:
                    if (!_isWorking)
                    {
                        SendMessage(nodeMessage);
                        _isWorking = true;
                        _stepCount = 0;
                        RepeatCount = 0;
                        _subNodes[0].NodeEvent(nodeMessage);
                    }
                    break;
                case NodeMsg.Succeed:
                    if (_stepCount < _subNodes.Count - 1)
                    {
                        _subNodes[++_stepCount].NodeEvent(NodeMsg.Start);
                        return;
                    }
                    //the last sub node will do this: all successed
                    if (++RepeatCount < RepeatLimit|| RepeatLimit == 0) NodeEvent(NodeMsg.Start);//repeat with repeating count
                    else SendMessage(nodeMessage);//if repeat forever, never send succeed msg
                    break;
                case NodeMsg.Fail:
                case NodeMsg.REQ_Abort:
                    RepeatCount = 0;
                    StopAllSubNodes();
                    _isWorking = false;
                    SendMessage(nodeMessage);
                    break;
                case NodeMsg.CMD_Stop:
                    if (_isWorking)
                    {
                        RepeatCount = 0;
                        StopAllSubNodes();
                        _isWorking = false;
                    }
                    break;
                default:
                    break;
            }
        }
    }
}